/******************************************************************************
	This file is a part of the Snapshot Bioinformatics Project

	Copyright (C) 2012-2013 Jarom Schow

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#ifndef GEN_BANK_PARSER_H
#define GEN_BANK_PARSER_H

#include "SeqParser.h"

#include <QtCore/QString>
#include <QtCore/QList>

#include "SeqLocation.h"

namespace Bio {

class SeqFeature;
class SeqReference;
class SeqRange;
class Progress;

class BIO_EXPORT GenBankParser : public SeqParser {
public:
	GenBankParser();
	virtual ~GenBankParser();

	virtual bool	parse( QIODevice &dev );

	virtual int			getNumRecords() const;
	virtual SeqRecord&	getRecord( int which );
	virtual SeqRecord	getRecord( int which ) const;

	virtual QMutableListIterator<SeqRecord>	getMutableRecordIterator();
	virtual QListIterator<SeqRecord>		getRecordIterator() const;

private:

	enum ParseMode { None, Locus, Definition, Accession, Version, DBLink, Keywords, Source, 
					Organism, Lineage, Reference, Authors, Title, Journal, Pubmed, Comment,
					Features, Origin } m_parseMode;

	enum FeatureMode { Invalid, Location, Qualifier } m_featureMode;

	int				m_lineNo;
	QByteArray		m_text;
	SeqRecord		*m_curRecord;
	SeqFeature		*m_curFeature;
	SeqReference	*m_curReference;

	QList<SeqRecord>	m_seqRecords;

	void	lineError( const QString &msg );
	void	lineWarning( const QString &msg );

	bool	startRecord();
	bool	endRecord();
	bool	startSection( ParseMode mode );
	bool	startReference();
	bool	endReference();
	bool	startFeature( const QString &type );
	bool	endFeature();
	bool	startQualifier( char *line );
	bool	endQualifier();
	bool	setLocation();
	bool	setQualifier();
	bool	addText( char *line, int offset );

	QByteArray	getAll( char *line, int offset );
	QByteArray	getAllStripped( char *line, int offset );
	QByteArray	getNextToken( char *&line );

	bool	parseLocus( char *line );
	bool	parseVersion( char *line );
	bool	parseSource( char *line );
	bool	parseOrganism( char *line );
	bool	parseReference( char *line );
	bool	parseFeatures( char *line );

	bool	parseLocation( const QByteArray &str, SeqRange &range, SeqLocation::Strand strand );
	bool	parseLocations( const QByteArray &str, SeqRange &range, SeqLocation::Strand strand );
	bool	parseStartEnd( const QByteArray &str, int &start, int &end );

	QList<QByteArray>	splitLocations( const QByteArray &str );
};

}; // Bio

#endif // GEN_BANK_PARSER_H